/**
 * 
 */
package t4j.concurrency;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

//计数器
class Count{
	private int count = 0 ;
	private Random rand = new Random(47);
	
	//必须加锁，保证count的访问同步
	public synchronized int increment(){
		int temp = count;
		
		//取消该方法synchronized关键字的话，这里会增加一半的机会做出让步，使问题更快的发生
		if(rand.nextBoolean())
			Thread.yield();
		
		return (count = ++temp);
	}
	
	public synchronized int value(){
		return count;
	}
}

//大门
class Entrance implements Runnable{
	private static Count count = new Count();//静态域，多对象共享一个
	
	private static List<Entrance> entrances = new ArrayList<Entrance>();//静态list
	
	private int number = 0;
	
	private final int id;
	
	private static volatile boolean canceled = false;
	//原子操作在一个volatile域
	public static void cancel(){ 
		canceled = true;
	}
	
	public Entrance(int id) {
		this.id = id;
		entrances.add(this);//把任务放进一个list里保存
	}
	
	@Override
	public void run() {
		
		while(!canceled){
			
			synchronized(this) {
				++number;
			}
			
			System.out.println(this + " Total: " + count.increment());
			
			try{
				TimeUnit.MILLISECONDS.sleep(100);
			}catch (InterruptedException e){
				System.out.println("sleep interrupted");
			}
		}
		
		System.out.println("Stopping " + this);
		
	}
	
	public synchronized int getValue(){
		return number;
	}
	
	public static int getTotalCount(){
		return count.value();
	}
	
	public static int sumEntrances(){
		int sum = 0 ;
		
		for(Entrance entrance : entrances)
			sum += entrance.getValue();
		
		return sum;
	}
	
	@Override
	public String toString() {
		return "Entrance " + id + ": " + getValue();
	}
	
	
}

//花园
public class OranmentalGarden {
	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();
		
		for(int i = 0 ; i < 5;i++)
			exec.execute(new Entrance(i));
		
		TimeUnit.SECONDS.sleep(3);
		
		Entrance.cancel();
		
		exec.shutdown();//停止所有线程，不中断线程还会继续运行
		
		//等待每个任务结束，如果所有的任务在超时时间达到之前全部结束，
		//则返回true,否则返回false，表示不是所有的任务都已经结束了。
		if(!exec.awaitTermination(250, TimeUnit.MILLISECONDS))
			System.out.println("Some tasks were not terminated!");
		
		System.out.println("Total: " + Entrance.getTotalCount());
		System.out.println("Sum of Entrances: " + Entrance.sumEntrances());
	}
}
